package com.book.modules.util;

import com.baomidou.dynamic.datasource.toolkit.CryptoUtils;
import com.baomidou.mybatisplus.core.exceptions.MybatisPlusException;
import com.book.common.lang.Tuple2;
import org.apache.commons.lang3.StringUtils;
import org.jasypt.encryption.pbe.StandardPBEStringEncryptor;

import java.util.Scanner;

/**
 * Description：加密数据库
 *
 * @Author： leo.xiong
 * @CreateDate： 2020/04/07 14:19
 * @Email： leo.xiong@suyun360.com
 * Version：1.0
 */
public class EncryptionUtil {
    /**
     * 秘钥
     */
    private static final String KEY_VALUE = "BOOK123LEOXYZ";

    private static final String ALGORITHM_INFO = "PBEWithMD5AndDES";

    private static final String PASSWORD_INFO = "EWRREWRERWECCCXC";

    /**
     * 用户名密码加密
     */
    public static void encryptionJDBC() {
        StandardPBEStringEncryptor standardPBEStringEncryptor = new StandardPBEStringEncryptor();
        /*配置文件中配置如下的算法*/
        standardPBEStringEncryptor.setAlgorithm(ALGORITHM_INFO);
        /*配置文件中配置的password*/
        standardPBEStringEncryptor.setPassword(PASSWORD_INFO);
        String username = standardPBEStringEncryptor.encrypt(scanner("登录名名"));
        String password = standardPBEStringEncryptor.encrypt(scanner("数据库密码"));
        System.out.println("username=" + username);
        System.out.println("password=" + password);
    }

    /**
     * 加密redis密码
     */
    public static void encryptionRedis() {
        StandardPBEStringEncryptor standardPBEStringEncryptor = new StandardPBEStringEncryptor();
        standardPBEStringEncryptor.setPassword(PASSWORD_INFO);
        String password = standardPBEStringEncryptor.encrypt(scanner("redis密码"));
        System.out.println("password=" + password);
    }

    /**
     * 秘钥加密，私钥加密，公钥解密
     *
     * @param value
     * @return Tuple2<String, String> key1位公钥，key2位加密后的值
     */
    public static Tuple2<String, String> secretEncryption(String value) {
        return secretEncryption(value, KEY_VALUE);
    }

    /**
     * 自定义秘钥信息
     *
     * @param value
     * @param secret
     * @return
     */
    public static Tuple2<String, String> secretEncryption(String value, String secret) {
        String[] arr = CryptoUtils.genKeyPair(secret.hashCode() % 2048);
        try {
            return new Tuple2<>(arr[1], CryptoUtils.encrypt(arr[0], value));
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 秘钥解密
     *
     * @param tuple2
     * @return
     */
    public static String secretDecrypt(Tuple2<String, String> tuple2) {
        try {
            return CryptoUtils.decrypt(tuple2._1(), tuple2._2());
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 普通加密
     *
     * @param value
     * @return
     */
    public static String encryption(String value) {
        try {
            return CryptoUtils.encrypt(value);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 普通解密
     *
     * @param value
     * @return
     */
    public static String decrypt(String value) {
        try {
            return CryptoUtils.decrypt(value);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * <p>
     * 读取控制台内容
     * </p>
     */
    private static String scanner(String tip) {
        Scanner scanner = new Scanner(System.in);
        StringBuilder help = new StringBuilder();
        help.append("请输入" + tip + "：");
        System.out.println(help.toString());
        if (scanner.hasNext()) {
            String ipt = scanner.next();
            if (StringUtils.isNotEmpty(ipt)) {
                return ipt;
            }
        }
        throw new MybatisPlusException("请输入正确的" + tip + "！");
    }

    public static void main(String[] args) {
        System.out.println(decrypt(encryption("熊浪")));
        System.out.println(secretDecrypt(secretEncryption("熊浪")));
    }
}
